﻿//////////////////////////////////////////////////////////////////////////////
//
// Copyright © 1998-2024 Glodon Company Limited.
//
// Licensed under the MIT License
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the “Software”),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//////////////////////////////////////////////////////////////////////////////


#include "GnufDynamicZoneRefreshManager.h"
#include "GnufExplorerBlockManager.h"
#include "GnufModelViewDefine.h"
#include "GnufPropertyPallet.h"
#include "CommandParameters.h"
#include "ComponentEditorGnufMainWindow.h"
#include "ComponentEditorGnufMainWindowEvent.h"
#include "ComponentEditorGnufUICommandIds.h"
#include "ComponentEditorConfigTool.h"
#include "FilePath.h"
#include "GbmpFileSystem.h"
#include "GmViewType.h"
#include "GnufBlock.h"
#include "GnufButtonToolDefinition.h"
#include "GnufDropdownMenuToolDefinition.h"
#include "GnufInfo.h"
#include "GnufMessageBoardInterface.h"
#include "GnufNotificationCenter.h"
#include "GnufNotificationCenterEventArgs.h"
#include "GnufToolDefinition.h"
#include "GnufTree.h"
#include "GnufWelcomePanelEx.h"
#include "GnufWorkBench.h"
#include "GnufDynamicPanel.h"
#include "GnufAssistantPanel.h"
#include "GnufPreferences.h"
#include "GnufDynamicZoneButtonStylePreferenceEntry.h"
#include "IApplicationWindowEvent.h"
#include "ICommandManager.h"
#include "IDocument.h"
#include "IModelView.h"
#include "IUiDocument.h"
#include "IUiDocumentEvent.h"
#include "IUiDocumentEventArgs.h"
#include "IUiDocumentEventHandler.h"
#include "IUiDocumentViewManager.h"
#include "LatestDirManager.h"
#include "LatestOpenedManager.h"
#include <QtCore/QUrl>
#include "GnufButtonEx.h"
#include "GnufUtility.h"
#include "GnufWindowTitleBar.h"
#include "CmdAvailibilityUtils.h"

#include "EnableCompileWarning_The_LAST_IncludeInCpp.h"

using namespace gcmp;
using namespace gnuf;
using namespace gfam;

namespace {
    gnuf::Preferences* GetMinorPreferences()
    {
        if (gnuf::WorkBench* wb = gnuf::WorkBench::get())
            return wb->minorPreferences();

        DBG_WARN(L"Failed to get the preference!", L"paramodel", L"2024-02-20");
        return nullptr;
    }

    gnuf::EButtonDisplayStyle ReadPanelButtonStyle(const std::wstring& dynamicPanelKey)
    {
        if (const gnuf::Preferences* preferences = ::GetMinorPreferences())
            if (const gnuf::PreferenceEntry* entry = preferences->entryBy(dynamicPanelKey))
                if (const DynamicZoneButtonStylePreferenceEntry* buttonStyle = entry->constCast<gnuf::DynamicZoneButtonStylePreferenceEntry>())
                {
                    return buttonStyle->value();
                }

        return EButtonDisplayStyle::eDefault;
    }
    void WritePanelButtonStyle(const std::wstring& dynamicPanelKey, EButtonDisplayStyle style)
    {
        if (gnuf::Preferences* preferences = ::GetMinorPreferences())
            if (gnuf::PreferenceEntry* entry = preferences->rEntryBy(dynamicPanelKey))
                if (DynamicZoneButtonStylePreferenceEntry* buttonStyle = entry->cast<gnuf::DynamicZoneButtonStylePreferenceEntry>())
                    if (style != buttonStyle->value())
                    {
                        buttonStyle->setValue(style);
                        preferences->persist();
                    }
    }
}
namespace gfam
{
    bool CheckLatestOpenedLocalProject(const std::wstring& filePath)
    {
        if (gcmp::FileInfo(filePath).Exists()) return true;
        gnuf::ShowMessageBoard(GBMP_TR(L"本地工程文件不存在"), GBMP_TR(L"提示"));

        LatestOpenedManager* mgr = LatestOpenedManager::Get();
        DBG_WARN_AND_RETURN_FALSE_UNLESS(mgr, L"LatestOpenedManager is null ", L"paramodel", L"2024-02-20");

        LatestOpenedLocalInfo delInfo = mgr->RemoveLatestOpenedLocalOf(filePath);
        DBG_WARN_AND_RETURN_FALSE_UNLESS(delInfo.isValid(), L"delInfo is not in the latest opened list ", L"paramodel", L"2024-02-20");

        ComponentEditorGnufMainWindow* pMainWindow = gcmp::quick_cast<ComponentEditorGnufMainWindow>(gnuf::GnufMainWindow::get());
        DBG_WARN_AND_RETURN_FALSE_UNLESS(pMainWindow, L"pMainWindow is null", L"paramodel", L"2024-02-20");
        pMainWindow->RemoveLatestOpenedRecord(delInfo);

        return false;
    }
}

namespace gfam 
{
    static const std::uint8_t s_btnLoginId(0);
    static const std::uint8_t s_btnApplyForTrial(1);
    
    class ComponentEditorGnufMainWindowImpl
        : public gnuf::IWelcomePanelEventHandler
        , public gcmp::IUiDocumentEventHandler
    {
    public:
        explicit ComponentEditorGnufMainWindowImpl(ComponentEditorGnufMainWindow *);
        ~ComponentEditorGnufMainWindowImpl();

        void initialize();
        void RefreshLatestOpenedList();

        IApplicationWindowEvent* GetMainWindowEvent();

    protected:
        // Inherits from gnuf::IWelcomePanelEventHandler...gcmp
        virtual void onWelcomePanelButtonClicked(gnuf::WelcomePanelPushButton *) override;
        virtual void onWelcomePanelLastestOpenedListClicked(gnuf::TreeNode*) override;
        // Inherits from gcmp::IUiDocumentEventHandler...
        virtual void On(gcmp::IUiDocumentEventArgs*) override;

    private:
        void initializeEnvironment();
        void addWelcomeProjectButton(gnuf::WelcomePanelProjectBlock*, const std::wstring&, const std::string& uniqueString);
        void addWelcomeSampleButton(WelcomePanelSampleBlock*, const std::wstring&, const std::string& uniqueString);
        void onApplyForTrial();
        
        ComponentEditorGnufMainWindow * m_mainWnd;
        OwnerPtr<IApplicationWindowEvent> m_pMainWindowEvent; // 主窗口事件
    };
    
    ComponentEditorGnufMainWindowImpl::ComponentEditorGnufMainWindowImpl(ComponentEditorGnufMainWindow * mainWnd)
        : m_mainWnd(mainWnd)
    {
        if (gcmp::IUiDocumentViewManager::Get())
        {
            if (gcmp::IUiDocumentViewManager::Get()->GetUiDocumentEvent())
            {
                gcmp::IUiDocumentViewManager::Get()->GetUiDocumentEvent()->Add(this);
            }
        }

        m_pMainWindowEvent = NEW_AS_OWNER_PTR(ComponentEditorMainWindowEvent, L"MainWindowEvent", m_mainWnd);
    }

    ComponentEditorGnufMainWindowImpl::~ComponentEditorGnufMainWindowImpl()
    {
        //
        // Donot listen to the events from the welcome panel, any more.
        gnuf::WorkBench * workBench = gnuf::GnufMainWindow::workBench();
        DBG_WARN_AND_RETURN_VOID_UNLESS(workBench, L"", L"", L"");
        gnuf::WelcomePanelEx * welcomePanel = workBench->welcomePanelEx();
        DBG_WARN_AND_RETURN_VOID_UNLESS(welcomePanel, L"", L"", L"");
        welcomePanel->unsubscribe(this);
    }

    void ComponentEditorGnufMainWindowImpl::initialize()
    {
        //
        // Initialize the collaboration environment...
        initializeEnvironment();

        //
        // Initialize the buttons on the welcome panel...
        DBG_WARN_AND_RETURN_VOID_UNLESS(m_mainWnd, L"", L"", L"");
        gnuf::WorkBench* workBench = m_mainWnd->workBench();
        DBG_WARN_AND_RETURN_VOID_UNLESS(workBench, L"", L"", L"");
        gnuf::WelcomePanelEx* welcomePanel = workBench->welcomePanelEx();
        DBG_WARN_AND_RETURN_VOID_UNLESS(welcomePanel, L"", L"", L"");

        welcomePanel->setBackgroundImage(L":/image/WelcomePanel/Background", L"dot");
        if (welcomePanel->loginBlock())
        {
            if (welcomePanel->loginBlock()->loginButton())
            {
                welcomePanel->loginBlock()->loginButton()->setUserData(s_btnLoginId);
            }

            if (welcomePanel->loginBlock()->applyTrialButtonButton())
            {
                welcomePanel->loginBlock()->applyTrialButtonButton()->setUserData(s_btnApplyForTrial);
            }
        }

        if (welcomePanel->getRecentList())
        {
            welcomePanel->getRecentList()->setEmptyListBackgroundImage(L":/image/WelcomePanel/EmptyList", L"empty");
            welcomePanel->getRecentList()->setEmptyListText(GBMP_TR(L"无最近打开记录"));
        }

        auto productProfessional = ComponentEditorConfigTool::GetCurrentProductProfessional();
        {
            gnuf::WelcomePanelProjectBlock* localOpenBlock = welcomePanel->addProjectBlock(L"Open");
            addWelcomeProjectButton(localOpenBlock, OPEN_LOCAL_FAMILY_DOCUMENT_COMMAND, "WelcomePanel::OpenLocalDocument");

            gnuf::WelcomePanelProjectBlock* localNewtBlock = welcomePanel->addProjectBlock(L"New");
            if (L"AppParamodel" == productProfessional)
            {
                addWelcomeProjectButton(localNewtBlock, NEW_LOCAL_FAMILY_DOCUMENT_FROM_GAP_TEMPLATE_COMMAND, "WelcomePanel::NewLocalFamilyDocumentFromGapTemplateCommand");
                addWelcomeProjectButton(localNewtBlock, NEW_LOCAL_FAMILY_DOCUMENT_FROM_GST_TEMPLATE_COMMAND, "WelcomePanel::NewLocalFamilyDocumentFromGstTemplateCommand");
                addWelcomeProjectButton(localNewtBlock, NEW_LOCAL_FAMILY_DOCUMENT_FROM_GMEP_TEMPLATE_COMMAND, "WelcomePanel::NewLocalFamilyDocumentFromGMepTemplateCommand");
                addWelcomeProjectButton(localNewtBlock, NEW_LOCAL_FAMILY_DOCUMENT_FROM_GROAD_TEMPLATE_COMMAND, "WelcomePanel::NewLocalFamilyDocumentFromGroadTemplateCommand");
                addWelcomeProjectButton(localNewtBlock, NEW_LOCAL_FAMILY_DOCUMENT_FROM_BIMMAKE_TEMPLATE_COMMAND, "WelcomePanel::NewLocalFamilyDocumentFromBimmakeTemplateCommand");
                addWelcomeProjectButton(localNewtBlock, NEW_LOCAL_FAMILY_DOCUMENT_FROM_DECO_TEMPLATE_COMMAND, "WelcomePanel::NewLocalFamilyDocumentFromDecoTemplateCommand");
            }
            else if (L"AppGarch" == productProfessional)
            {
                addWelcomeProjectButton(localNewtBlock, NEW_LOCAL_FAMILY_DOCUMENT_FROM_GAP_TEMPLATE_COMMAND, "WelcomePanel::NewLocalFamilyDocumentFromGapTemplateCommand");
            }
            else if (L"AppGstr" == productProfessional)
            {
                addWelcomeProjectButton(localNewtBlock, NEW_LOCAL_FAMILY_DOCUMENT_FROM_GST_TEMPLATE_COMMAND, "WelcomePanel::NewLocalFamilyDocumentFromGstTemplateCommand");
            }
            else if (L"AppGmep" == productProfessional)
            {
                addWelcomeProjectButton(localNewtBlock, NEW_LOCAL_FAMILY_DOCUMENT_FROM_GMEP_TEMPLATE_COMMAND, "WelcomePanel::NewLocalFamilyDocumentFromGMepTemplateCommand");
            }
            else if (L"AppGroad" == productProfessional)
            {
                addWelcomeProjectButton(localNewtBlock, NEW_LOCAL_FAMILY_DOCUMENT_FROM_GROAD_TEMPLATE_COMMAND, "WelcomePanel::NewLocalFamilyDocumentFromGroadTemplateCommand");
            }
            else if (L"AppBimmake" == productProfessional)
            {
                addWelcomeProjectButton(localNewtBlock, NEW_LOCAL_FAMILY_DOCUMENT_FROM_BIMMAKE_TEMPLATE_COMMAND, "WelcomePanel::NewLocalFamilyDocumentFromBimmakeTemplateCommand");
            }
            else if (L"AppDeco" == productProfessional)
            {
                addWelcomeProjectButton(localNewtBlock, NEW_LOCAL_FAMILY_DOCUMENT_FROM_DECO_TEMPLATE_COMMAND, "WelcomePanel::NewLocalFamilyDocumentFromDecoTemplateCommand");
            }
            addWelcomeProjectButton(localNewtBlock, NEW_LOCAL_FAMILY_DOCUMENT_COMMAND, "WelcomePanel::NewLocalDocument");
        }

        {
            if (L"AppBimmake" != productProfessional)
            {
                gnuf::WelcomePanelSampleBlock* dcSampleBlock = welcomePanel->addSampleBlock(L"SampleGac");
                addWelcomeSampleButton(dcSampleBlock, OPEN_LOCAL_FAMILY_DOCUMENT_FROM_GAP_SAMPLE_COMMAND, "WelcomePanel::OpenLocalFamilyDocumentFromGapSampleCommand");
                addWelcomeSampleButton(dcSampleBlock, OPEN_LOCAL_FAMILY_DOCUMENT_FROM_GST_SAMPLE_COMMAND, "WelcomePanel::OpenLocalFamilyDocumentFromGstSampleCommand");
                addWelcomeSampleButton(dcSampleBlock, OPEN_LOCAL_FAMILY_DOCUMENT_FROM_GMEP_SAMPLE_COMMAND, "WelcomePanel::OpenLocalFamilyDocumentFromGMepSampleCommand");
                addWelcomeSampleButton(dcSampleBlock, OPEN_LOCAL_FAMILY_DOCUMENT_FROM_GROAD_SAMPLE_COMMAND, "WelcomePanel::OpenLocalFamilyDocumentFromGroadSampleCommand");
                addWelcomeSampleButton(dcSampleBlock, OPEN_LOCAL_FAMILY_DOCUMENT_FROM_BIMMAKE_SAMPLE_COMMAND, "WelcomePanel::OpenLocalFamilyDocumentFromBIMMAKESampleCommand");
                addWelcomeSampleButton(dcSampleBlock, OPEN_LOCAL_FAMILY_DOCUMENT_FROM_OTHER_SAMPLE_COMMAND, "WelcomePanel::OpenLocalFamilyDocumentFromOtherSampleCommand");
            }
        }

        welcomePanel->setLoggedIn(true);
        welcomePanel->subscribe(this);
    }

    void ComponentEditorGnufMainWindowImpl::initializeEnvironment()
    {
    }
    
    void ComponentEditorGnufMainWindowImpl::addWelcomeProjectButton(gnuf::WelcomePanelProjectBlock* block, const std::wstring& cmdId, const std::string& uniqueString)
    {
        using namespace gnuf;

        DBG_WARN_AND_RETURN_VOID_UNLESS(block != nullptr, L"block is nullptr", L"paramodel", L"2024-02-20");
        DBG_WARN_AND_RETURN_VOID_UNLESS(ToolDefinitionManager::get() != nullptr, L"ToolDefinitionManager::get() is nullptr", L"paramodel", L"2024-02-20");

        if (ToolDefinition * toolDef = ToolDefinitionManager::get()->toolDefinitionBy(cmdId))
        {
            ButtonToolDefinition * buttonDef = toolDef->cast<ButtonToolDefinition>();
            DBG_WARN_AND_RETURN_VOID_UNLESS(buttonDef != nullptr, L"it is not a button", L"paramodel", L"2024-02-20");
            buttonDef->setIsRecordCmd(false);

            ButtonControl * buttonCtrl = buttonDef->buttonControl();
            DBG_WARN_AND_RETURN_VOID_UNLESS(buttonCtrl != nullptr, L"add button failed", L"paramodel", L"2024-02-20");
            Info* info = buttonCtrl->info();
            DBG_WARN_AND_RETURN_VOID_UNLESS(info != nullptr, L"info is nullptr", L"paramodel", L"2024-02-20");

            ButtonEx* button = block->addButton(NEW_AS_OWNER_PTR(gnuf::Info, info->caption(), info->tooltip(), info->iconDir()));
            DBG_WARN_AND_RETURN_VOID_UNLESS(button != nullptr, L"add button failed", L"paramodel", L"2024-02-20");
            button->setUniqueKey(gcmp::UniqueString::Find(uniqueString));
            button->setUserData(cmdId);
            button->setIsRecordUI(cmdId != OPEN_LOCAL_FAMILY_DOCUMENT_COMMAND);

            buttonCtrl->subscribe(button);
        }
    }

    void ComponentEditorGnufMainWindowImpl::addWelcomeSampleButton(WelcomePanelSampleBlock* block, const std::wstring& cmdId, const std::string& uniqueString)
    {
        using namespace gnuf;

        DBG_WARN_AND_RETURN_VOID_UNLESS(block != nullptr, L"block is nullptr", L"paramodel", L"2024-02-20");
        DBG_WARN_AND_RETURN_VOID_UNLESS(ToolDefinitionManager::get() != nullptr, L"ToolDefinitionManager::get() is nullptr", L"paramodel", L"2024-02-20");

        if (ToolDefinition * toolDef = ToolDefinitionManager::get()->toolDefinitionBy(cmdId))
        {
            ButtonToolDefinition * buttonDef = toolDef->cast<ButtonToolDefinition>();
            DBG_WARN_AND_RETURN_VOID_UNLESS(buttonDef != nullptr, L"it is not a button", L"paramodel", L"2024-02-20");
            buttonDef->setIsRecordCmd(false);

            ButtonControl * buttonCtrl = buttonDef->buttonControl();
            DBG_WARN_AND_RETURN_VOID_UNLESS(buttonCtrl != nullptr, L"add button failed", L"paramodel", L"2024-02-20");
            Info* info = buttonCtrl->info();
            DBG_WARN_AND_RETURN_VOID_UNLESS(info != nullptr, L"info is nullptr", L"paramodel", L"2024-02-20");

            gnuf::ButtonEx* button = block->addButton(NEW_AS_OWNER_PTR(gnuf::Info, info->caption(), info->tooltip(), info->iconDir()));
            DBG_WARN_AND_RETURN_VOID_UNLESS(button != nullptr, L"add button failed", L"paramodel", L"2024-02-20");
            button->setUniqueKey(gcmp::UniqueString::Find(uniqueString));
            button->setUserData(cmdId);
            button->setIsRecordUI(cmdId != OPEN_LOCAL_FAMILY_DOCUMENT_COMMAND);

            buttonCtrl->subscribe(button);
        }
    }

    void ComponentEditorGnufMainWindowImpl::onWelcomePanelButtonClicked(gnuf::WelcomePanelPushButton * btn)
    {
        try
        {
            const std::uint8_t id = btn->userData().cast<std::uint8_t>();
            switch (id)
            {
            case s_btnLoginId: break;
            case s_btnApplyForTrial: onApplyForTrial(); break;
            default: break;
            }
        }
        catch (const gcmp::anyimpl::bad_any_cast&){}
    }

    void ComponentEditorGnufMainWindowImpl::onWelcomePanelLastestOpenedListClicked(gnuf::TreeNode* node)
    {
        if (nullptr == node)
            return;
        try
        {
            if (node->userData().compatible(LatestOpenedLocalInfo()))
            {
                const LatestOpenedLocalInfo theInfo = node->userData().cast<LatestOpenedLocalInfo>();
                if (!CheckLatestOpenedLocalProject(theInfo.FilePath)) return;
                CommandParameters cmdPrams;
                cmdPrams.insert(std::pair<CommandParameterKey, CommandParameterValue>(L"FilePath", theInfo.FilePath));
                if (ICommandManager::Get())
                {
                    ICommandManager::Get()->SendCommand(L"gmComponentEditorOpenProject", cmdPrams);
                }
            }
            else
            {
                DBG_WARN(L"Failed to get the user data from the latest opened list!", L"paramodel", L"2024-02-20");
            }
        }
        catch (const gcmp::anyimpl::bad_any_cast&)
        {
            DBG_WARN(L"Failed to get the user data from the latest opened list!", L"paramodel", L"2024-02-20");
        }
    }

    void ComponentEditorGnufMainWindowImpl::RefreshLatestOpenedList()
    {
        DBG_WARN_AND_RETURN_VOID_UNLESS(m_mainWnd, L"", L"", L"");
        gnuf::WorkBench* workBench = m_mainWnd->workBench();
        DBG_WARN_AND_RETURN_VOID_UNLESS(workBench, L"", L"", L"");
        gnuf::WelcomePanelEx* welcomePanel = workBench->welcomePanelEx();
        DBG_WARN_AND_RETURN_VOID_UNLESS(welcomePanel, L"", L"", L"");
        WelcomePanelLastestOpenedList* recentList = welcomePanel->getRecentList();
        DBG_WARN_AND_RETURN_VOID_UNLESS(recentList, L"", L"", L"");

        {
            LatestOpenedManager* mgr = LatestOpenedManager::Get();
            DBG_WARN_AND_RETURN_VOID_UNLESS(mgr, L"LatestOpenedManager is null ", L"paramodel", L"2024-02-20");

            std::list<WelcomePanelLastestOpenedList::LastestOpenedRecord> lastestOpenedList;
            for (const auto & one : mgr->GetLatestOpenedLocalList())
            {
                const gcmp::FilePath filePath(one.FilePath);
                WelcomePanelLastestOpenedList::LastestOpenedRecord record(filePath.GetFileName(), one.GetOpenTimeString(), filePath.GetDirectoryName(), one);
                lastestOpenedList.emplace_back(record);
            }
            recentList->refresh(lastestOpenedList);
        }
    }

    IApplicationWindowEvent * ComponentEditorGnufMainWindowImpl::GetMainWindowEvent()
    {
        return m_pMainWindowEvent.get();
    }
    
    void ComponentEditorGnufMainWindowImpl::onApplyForTrial()
    {
        if (gcmp::ICommandManager::Get())
        {
            gcmp::ICommandManager::Get()->SendCommand(L"gapApplyForTrialCommand");
        }
    }

    void ComponentEditorGnufMainWindowImpl::On(gcmp::IUiDocumentEventArgs* args)
    {
        switch (args->GetType())
        {
        case gcmp::UiDocumentEventType::UiDocumentActivated:
        {
        }
        break;
        case gcmp::UiDocumentEventType::PreUiDocumentClose: 
        {
            gcmp::IUiDocument* pUIDoc = args->GetUiDocument();
            DBG_WARN_AND_RETURN_VOID_UNLESS(nullptr != pUIDoc, L"pUIDoc is nullptr!", L"paramodel", L"2024-02-20");
            gcmp::IDocument* pDoc = pUIDoc->GetDbDocument();
            DBG_WARN_AND_RETURN_VOID_UNLESS(nullptr != pDoc, L"pDoc is nullptr!", L"paramodel", L"2024-02-20");
            if (pDoc->GetWasSaved())
            {
                std::wstring filePath(pDoc->GetFilePath());
                StringUtil::ReplaceAll(filePath, L"/", L"\\"); // 确保路径中都是反斜杠
                if (FileInfo(filePath).Exists()) {
                    gcmp::OwnerPtr<LatestOpenedLocalInfo> info = NEW_AS_OWNER_PTR(LatestOpenedLocalInfo, filePath);
                    LatestOpenedManager * pLatestOpenedMgr = LatestOpenedManager::Get();
                    DBG_WARN_AND_RETURN_VOID_UNLESS(pLatestOpenedMgr, L"LatestOpenedManager is null ", L"paramodel", L"2024-02-20");
                    pLatestOpenedMgr->AddLatestOpenedLocal(LatestOpenedLocalInfo(filePath));
                }
            }

            //保存最近打开路径到json
            if (LatestDirManager::Get())
            {
                LatestDirManager::Get()->Save();
            }
        }
        break;
        default: 
        break;
        }
    }
}

ComponentEditorGnufMainWindow::ComponentEditorGnufMainWindow(
    const wchar_t * configurationsDirectory)
    : GnufMainWindow(configurationsDirectory)
{
    m_impl = NEW_AS_OWNER_PTR(ComponentEditorGnufMainWindowImpl, this);
    m_dynamicZoneRefreshManager = NEW_AS_OWNER_PTR(GnufDynamicZoneRefreshManager);

    if (gnuf::NotificationCenter::get())
    {
        gnuf::NotificationCenter::get()->subscribe(gnuf::ENotificationChannel::eOutput, this);
    }
}

ComponentEditorGnufMainWindow::~ComponentEditorGnufMainWindow()
{
    if (gnuf::NotificationCenter::get())
    {
        gnuf::NotificationCenter::get()->unsubscribe(gnuf::ENotificationChannel::eOutput, this);
    }

    ComponentEditorMainWindowEvent* pMainWindowEvent = dynamic_cast<ComponentEditorMainWindowEvent*>(GetMainWindowEvent());
    if (pMainWindowEvent)
    {
        ComponentEditorMainWindowEventArgs eventArgs(ApplicationWindowEventType::Closed);
        pMainWindowEvent->Emit(&eventArgs);
    }
}

std::wstring ComponentEditorGnufMainWindow::GetViewTypeDisplayName(const gcmp::IModelView* pModelView)
{
    const ExplorerBlock* pBlock = ExplorerBlockManager::getInstance()->findSourceBlock(pModelView);
    if (pBlock) return pBlock->getBlockName();
#pragma warning(push)
#pragma warning(disable: 4996)
    std::wstring viewType = pModelView->GetUserDataId();
#pragma warning(pop)
    std::wstring viewTypeName = GnufModelViewTypeUtil::GetModelViewTypeName(viewType);
    if (viewTypeName == L"未知视图类型")
    {
        if (viewType == BMVI_BaseLevel)
        {
            viewTypeName = GBMP_TR(L"平面视图");
        }
        else if (viewType == BMVI_Ceiling)
        {
            viewTypeName = GBMP_TR(L"天花板平面视图");
        }
        else if (viewType == BMVI_Right || viewType == BMVI_Left || viewType == BMVI_Front || viewType == BMVI_Back)
        {
            viewTypeName = GBMP_TR(L"立面视图");
        }
        else if (viewType == BMVI_3D)
        {
            viewTypeName = GBMP_TR(L"三维视图");
        }
        else
        {
            viewTypeName = L"未知视图类型";
        }
    }
    return viewTypeName;
}

bool ComponentEditorGnufMainWindow::Initialize()
{
    // 主窗口显示前发送事件
    ComponentEditorMainWindowEvent* pMainWindowEvent = dynamic_cast<ComponentEditorMainWindowEvent*>(GetMainWindowEvent());
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pMainWindowEvent, L"应用程序开始执行时获取主窗口事件对象失败。", L"paramodel", L"2024-02-20");
    {
        ComponentEditorMainWindowEventArgs eventArgs(ApplicationWindowEventType::PreFirstShow);
        pMainWindowEvent->Emit(&eventArgs);
    }

    DBG_WARN_AND_RETURN_FALSE_UNLESS(m_impl, L"m_impl is nullptr!", L"paramodel", L"2024-02-20");
    m_impl->initialize();
    gfam::GnufPropertyPallet::Initialize();
    bool result = GnufMainWindow::Initialize();

    {
        ComponentEditorMainWindowEventArgs eventArgs(ApplicationWindowEventType::Prepared);
        pMainWindowEvent->Emit(&eventArgs);
    }
    return result;
}

void ComponentEditorGnufMainWindow::onEvent(gnuf::INotificationCenterEventArgs* pArgs)
{
    if (gnuf::WorkStagePostSwitchedEventArgs* pWorkStagePostSwitchedArgs = quick_cast<gnuf::WorkStagePostSwitchedEventArgs>(pArgs))
    {
        if ((gnuf::EWorkStage::eWelcomePanel == pWorkStagePostSwitchedArgs->oldWorkStage())  &&
            (gnuf::EWorkStage::eEnd == pWorkStagePostSwitchedArgs->newWorkStage()))
            return;

        if (gnuf::EWorkStage::eWelcomePanel == pWorkStagePostSwitchedArgs->newWorkStage())
        {
            DBG_WARN_AND_RETURN_VOID_UNLESS(m_impl, L"m_impl is nullptr!", L"paramodel", L"2024-02-20");
            m_impl->RefreshLatestOpenedList();
        }

        gnuf::WorkBench* pWorkBench = pWorkStagePostSwitchedArgs->workBench();
        DBG_WARN_AND_RETURN_VOID_UNLESS(pWorkBench, L"pWorkBench is nullptr!", L"paramodel", L"2024-02-20");
        gnuf::WindowTitleBar * wndTitleBar = pWorkBench->windowTitleBar();
        DBG_WARN_AND_RETURN_VOID_UNLESS(wndTitleBar, L"wndTitleBar is nullptr!", L"paramodel", L"2024-02-20");

        if (EWorkStage::eDesktop == pWorkStagePostSwitchedArgs->newWorkStage()) {
            wndTitleBar->setWindowTitleVisible(L"MainWindowTitle", false);
        }
        else if (EWorkStage::eWelcomePanel == pWorkStagePostSwitchedArgs->newWorkStage()) {
            wndTitleBar->setWindowTitleVisible(L"MainWindowTitle", true);
        }

    }
    else if (gnuf::WorkStagePreSwitchedEventArgs* pWorkStagePreSwitchedArgs = quick_cast<gnuf::WorkStagePreSwitchedEventArgs>(pArgs))
    {
        if (gnuf::EWorkStage::eWelcomePanel == pWorkStagePreSwitchedArgs->oldWorkStage() && EWorkStage::eDesktop == pWorkStagePreSwitchedArgs->newWorkStage())
        {
            // 在进入文档环境之后，构建Assistant之前，需要刷新一下按钮的显隐状态
            gnuf::Utility::refreshStatus(true);
        }
    }
    else if (GetDynamicPanelEventArgs* evt = gcmp::quick_cast<gnuf::GetDynamicPanelEventArgs>(pArgs))
    {
        gcmp::OwnerPtr<DynamicPanel> firstPanel = NEW_AS_OWNER_PTR(gnuf::DynamicPanel, L"1st_DynamicPanel", gcmp::UniqueString::Find("1st_DynamicPanel"), GBMP_TR(L"选择种类"), gnuf::EItemType::eBlock, true);
        firstPanel->setButtonDisplayStyle(ReadPanelButtonStyle(L"1st_DynamicPanel"));
        evt->add(TransferOwnership(firstPanel));

        gcmp::OwnerPtr<DynamicPanel> secondPanel = NEW_AS_OWNER_PTR(gnuf::DynamicPanel, L"2nd_DynamicPanel", gcmp::UniqueString::Find("2nd_DynamicPanel"), GBMP_TR(L"创建方式"), gnuf::EItemType::eBlock, true);
        secondPanel->setButtonDisplayStyle(ReadPanelButtonStyle(L"2nd_DynamicPanel"));
        evt->add(TransferOwnership(secondPanel));

        evt->add(NEW_AS_OWNER_PTR(gnuf::DynamicPanel, L"ActionDialog", gcmp::UniqueString::Find("ActionDialog"), GBMP_TR(L"动态面板 3"), gnuf::EItemType::eNameValuePairs, false));
        evt->add(NEW_AS_OWNER_PTR(gnuf::DynamicPanel, L"ScenarioDialog", gcmp::UniqueString::Find("ScenarioDialog"), GBMP_TR(L"动态面板 4"), gnuf::EItemType::eNameValuePairs, false));
        AssistantPanel* pAssistantPanel = AssistantPanel::get();
        DBG_WARN_AND_RETURN_VOID_UNLESS(nullptr != pAssistantPanel, L"The assistantPanel is not exist", L"paramodel", L"2024-02-20");
        pAssistantPanel->setButtonDisplayStyle(ReadPanelButtonStyle(pAssistantPanel->key()));
    }
    else if (DynamicPanelButtonStyleChangedEventArgs* evt = gcmp::quick_cast<gnuf::DynamicPanelButtonStyleChangedEventArgs>(pArgs))
    {
        const std::wstring& key = evt->key();
        EButtonDisplayStyle style = evt->style();
        WritePanelButtonStyle(key, style);
    }
    else if (gnuf::SwitchWorkspaceEventArgs * evt = quick_cast<gnuf::SwitchWorkspaceEventArgs>(pArgs))
    {
        if(CmdAvailibilityUtils::IsInEditMode())
            evt->setApproved(false);
    }
}

void ComponentEditorGnufMainWindow::RemoveLatestOpenedRecord(const LatestOpenedLocalInfo& info)
{
    DBG_WARN_AND_RETURN_VOID_UNLESS(m_impl != nullptr, L"m_impl为空", L"paramodel", L"2024-02-20");
    gnuf::WorkBench * workBench = this->workBench();
    DBG_WARN_AND_RETURN_VOID_UNLESS(workBench, L"", L"", L"");
    gnuf::WelcomePanelEx * welcomePanel = workBench->welcomePanelEx();
    DBG_WARN_AND_RETURN_VOID_UNLESS(welcomePanel, L"", L"", L"");
    WelcomePanelLastestOpenedList* recentList = welcomePanel->getRecentList();
    DBG_WARN_AND_RETURN_VOID_UNLESS(recentList, L"", L"", L"");
    const gcmp::FilePath filePath(info.FilePath);
    WelcomePanelLastestOpenedList::LastestOpenedRecord recordInfo(filePath.GetFileName(), info.GetOpenTimeString(), filePath.GetDirectoryName(), info);
    recentList->remove(recordInfo);
}

void ComponentEditorGnufMainWindow::refreshLatestOpenedList()
{
    DBG_WARN_AND_RETURN_VOID_UNLESS(m_impl != nullptr, L"m_impl为空", L"paramodel", L"2024-02-20");
    m_impl->RefreshLatestOpenedList();
}

GnufDynamicZoneRefreshManager* ComponentEditorGnufMainWindow::dynamicZoneRefreshManager()
{
    return m_dynamicZoneRefreshManager.get();
}

IApplicationWindowEvent * gfam::ComponentEditorGnufMainWindow::GetMainWindowEvent()
{
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(m_impl != nullptr, L"m_impl为空", L"paramodel", L"2024-02-20");
    return m_impl->GetMainWindowEvent();
}
